package com.aw.baselib.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Base64;
import android.widget.ImageView;

import com.aw.baselib.base.AwBaseApplication;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

import androidx.core.graphics.drawable.DrawableCompat;

@SuppressLint("RtlHardcoded")
public class AwBitmapUtils {
	private static final Set<String> SUFFIXS = new HashSet<String>();
	static{
		SUFFIXS.add("jpg");
		SUFFIXS.add("jpeg");
		SUFFIXS.add("png");
		SUFFIXS.add("bmp");
		SUFFIXS.add("gif");
	}
	
	/**
	 * 将Bitmap转换成Base64字符串
	 * @param bitmap
	 * @return
	 */
	public static String bitmapToBase64(Bitmap bitmap){
		String string = null;
		ByteArrayOutputStream bStream = new ByteArrayOutputStream();
		bitmap.compress(CompressFormat.PNG, 100, bStream);
		byte[] bytes = bStream.toByteArray();
		string = Base64.encodeToString(bytes, Base64.DEFAULT);
		return string;
	}
	
	/**
	 * 将Base64字符串转换成Bitmap
	 * @param content
	 * @return
	 */
	public static Bitmap base64ToBitmp(String content){
		Bitmap b = null;
		try{
			byte[] bs = Base64.decode(content, Base64.DEFAULT);
			b = BitmapFactory.decodeByteArray(bs, 0, bs.length);
		}catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	// 提取图像Alpha位图
	public static Bitmap getAlphaBitmap(Context context, int resId) {

		Bitmap mBitmap = BitmapFactory.decodeResource(context.getResources(), resId);
		// BitmapDrawable的getIntrinsicWidth（）方法，Bitmap的getWidth（）方法
		// 注意这两个方法的区别
		// Bitmap mAlphaBitmap =
		// Bitmap.createBitmap(mBitmapDrawable.getIntrinsicWidth(),
		// mBitmapDrawable.getIntrinsicHeight(), Config.ARGB_8888);
		Bitmap mAlphaBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Config.ARGB_8888);

		Canvas mCanvas = new Canvas(mAlphaBitmap);
		Paint mPaint = new Paint();

		mPaint.setColor(Color.BLUE);
		// 从原位图中提取只包含alpha的位图
		Bitmap alphaBitmap = mBitmap.extractAlpha();
		// 在画布上（mAlphaBitmap）绘制alpha位图
		mCanvas.drawBitmap(alphaBitmap, 0, 0, mPaint);

		return mAlphaBitmap;
	}

	/**
	 * 旋转图片
	 * @param context 当前上下文
	 * @param resId 要进行旋转的图片资源ID
	 * @param degree 旋转的度数
	 * @return
	 */
	public static Bitmap getRotatedBitmap(Context context, int resId, int degree){
		
        Bitmap mBitmap = BitmapFactory.decodeResource(context.getResources(), resId);
        Bitmap mRotateBitmap = getRotatedBitmap(mBitmap,degree);  
          
        return mRotateBitmap;  
	}

	/**
	 * 旋转图片
	 * @param mBitmap 要进行旋转的图片
	 * @param degree 旋转的度数
	 */
	public static Bitmap getRotatedBitmap(Bitmap mBitmap,int degree) {
		try {
			int width = mBitmap.getWidth();  
			int height = mBitmap.getHeight();  
			  
			Matrix matrix = new Matrix();  
			matrix.preRotate(degree);  
			Bitmap mRotateBitmap = Bitmap.createBitmap(mBitmap, 0, 0, width, height, matrix, true);
			return mRotateBitmap;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 计算图片大小需要调整的比例
	 * @param options 操作对象
	 * @param reqWidth 需要的宽度
	 * @param reqHeight 需要的高度
	 * @return
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){
		//图片的原始宽和高
		int width = options.outWidth;
		int height = options.outHeight;
		int inSampleSize = 1;
		if(height >reqHeight || width>reqWidth){
			//计算目标图片的宽和高与图片原始的宽和高的比例
			final int heightRatio = Math.round((float)height/(float)reqHeight);
			final int widthRatio = Math.round((float)width/(float)reqWidth);
			//选择比例小的做为调整比例
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		}
		return inSampleSize;
	}
	
	/**
	 * 获取资源文件的图片
	 * @param res 资源管理对象
	 * @param resId 资源ID
	 * @param reqWidth 需要的宽度
	 * @param reqHeight 需要的高度
	 * @return
	 */
	public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
			int reqWidth, int reqHeight) {
	    // First decode with inJustDecodeBounds=true to check dimensions
	    final BitmapFactory.Options options = new BitmapFactory.Options();
	    options.inJustDecodeBounds = true;
	    BitmapFactory.decodeResource(res, resId, options);

	    // Calculate inSampleSize
	    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

	    // Decode bitmap with inSampleSize set
	    options.inJustDecodeBounds = false;
	    return BitmapFactory.decodeResource(res, resId, options);
	}
	
	/**
	 * 获取指定路径的图片
	 * @param path 图片路径
	 * @param reqWidth  需要的宽度
	 * @param reqHeight  需要的高度
	 * @return
	 */
	public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) {
		if(!AwFileUtil.fileExists(path)){
			return null;
		}
		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(path, options);
		
		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
		
		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeFile(path, options);
	}
	
	/**
	 * 将Drawable转化成Bitmap
	 * @param drawable 待转换的Drawable
	 * @return
	 */
	public static Bitmap drawableToBitmap(Drawable drawable) {
		Bitmap bitmap = Bitmap.createBitmap(
						drawable.getIntrinsicWidth(),
						drawable.getIntrinsicHeight(),
						drawable.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888: Config.RGB_565);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
		drawable.draw(canvas);
		return bitmap;
	}
	
	/** 保存图片到文件*/
	public static void saveBitmapToFile(Bitmap bitmap, String path)  {
		File file = new File(path);
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(file);
			if (bitmap.compress(CompressFormat.JPEG, 80, out)) {
				out.flush();
				out.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 将ImageView控件中的图片保存到文件
	 * @param imgView 
	 * @param path 图片保存路径
	 * @return 成功保存为图片文件则返回true，否则返回false
	 */
	public static boolean saveToFile(ImageView imgView,String path){
		if (imgView.getDrawable() == null)
			return false;
		
		Bitmap bmp = null;
		try {
			bmp = drawableToBitmap(imgView.getDrawable());
		} catch (Exception e) {
			return false;
		}
		if(bmp == null)
			return false;
		
		try {
			if(TextUtils.isEmpty(path))
				return false;
			else
				saveBitmapToFile(bmp,path);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		
		return true;
	}

	/**
	 * 绘制指定半径和颜色的实心圆，中心放文字
	 * @param radius 半径
	 * @param dotColor 圆点颜色
     * @param text 文本内容
     * @param textSize 字体大小
     * @param textColor 字体颜色
	 * @return
	 */
	public static Bitmap drawDotWithText(int radius, int dotColor, String text, float textSize, int textColor){
		int width = radius * 2;
        Bitmap dot = Bitmap.createBitmap(width, width, Config.ARGB_8888);
		Canvas c = new Canvas(dot);

        // Background Paint
		Paint p = new Paint();
		p.setAntiAlias(true);
		p.setStyle(Style.FILL);
		p.setColor(dotColor);
		c.drawCircle(radius, radius, radius, p);

        // TextPaint
        TextPaint textPaint = new TextPaint();
        textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setLinearText(true);
        textPaint.setColor(textColor);
        textPaint.setTextSize(textSize);

//        int pixel= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
//                textSize, getResources().getDisplayMetrics());

        if(text != null){
            float length = textPaint.measureText(text);//总长度
            float per = length / text.length();//一个字的长度
            int total = (int) (Math.sqrt(4 * radius * radius - textSize * textSize) / per);//总共可以放多少个字
            if(total > 0 && total < text.length()){
                text = text.substring(0, total);
            }else if(total == 0){
                text = "";
            }
            // x默认是字符的左边在屏幕的位置，如果设置了paint.setTextAlign(Paint.Align.CENTER);
            // 那就是字符的中心，y是指定这个字符baseline在屏幕上的位置。
            // textPaint.descent() + textPaint.ascent() = textHeight;
            c.drawText(text, radius, radius - (textPaint.descent() + textPaint.ascent()) / 2, textPaint);//要做5px偏移
        }
		return dot;
	}
	
	/**
	 * 绘制指定半径和颜色的实心圆
	 * @param radius
	 * @param color
	 * @return
	 */
	public static Bitmap drawDot(int radius, int color){
		Bitmap dot = Bitmap.createBitmap(radius * 2, radius * 2, Config.ARGB_8888);
		Canvas c = new Canvas(dot);
		Paint p = new Paint();
		p.setAntiAlias(true);
		p.setStyle(Style.FILL);
		p.setColor(color);
		c.drawCircle(radius, radius, radius, p);
		return dot;
	}
	
	/**
	 * 绘制列表条目的下一级标识箭头
	 * @param context
	 * @return
	 */
	public static Bitmap drawItemNextIndicator(Context context){
		return AwBitmapUtils.drawArrow(
				context, AwDisplayUtil.dip2px(context, 20), Color.GRAY, ArrowDirection.RIGHT);
	}
	
	/**
	 * 绘制的箭头
	 * @param context
	 * @param sideLen 边长，左、右方向时指箭头高度，上、下方向时指箭头宽度
	 * @param color
	 * @param direct
	 * @return
	 */
	public static Bitmap drawArrow(Context context, int sideLen, int color, ArrowDirection direct){
		
		int lineWidth = AwDisplayUtil.dip2px(context, 2);
		//规划箭头路径
		int offsetWidth = sideLen/4;
		Point end1 = new Point(offsetWidth + lineWidth, lineWidth);
		Point end2 = new Point(offsetWidth + lineWidth, sideLen - lineWidth);
		Point header = new Point(offsetWidth + sideLen/2, sideLen/2);
		
		Path arrowPath = new Path();
		arrowPath.reset();
		arrowPath.moveTo(end1.x, end1.y);
		arrowPath.lineTo(header.x, header.y);
		arrowPath.lineTo(end2.x, end2.y);
		
		Bitmap arrow = Bitmap.createBitmap(sideLen, sideLen, Config.ARGB_8888);
		Canvas c = new Canvas(arrow);
		Paint p = new Paint();
		p.setAntiAlias(true);
		p.setStyle(Style.STROKE);
		p.setStrokeWidth(lineWidth);
		p.setColor(color);
		c.drawPath(arrowPath, p);
		
		Bitmap result = direct.getDegree() == 0 
				? arrow : getRotatedBitmap(arrow, direct.getDegree());
		return result;
	}
	
	public static Bitmap drawCrossIcon(Context context, int sideLen, int color){
		return drawCrossIcon(context, sideLen, -1, color);
	}
	
	public static Bitmap drawDeclineIcon(Context context, int sideLen, int color){
		return drawDeclineIcon(context, sideLen, -1, color);
	}
	
	public static Bitmap drawDirectLeftTriangle(Context context, int size, int color, boolean solid){
		return drawTriangle(context, size, color, solid, ArrowDirection.LEFT);
	}
	public static Bitmap drawTriangle(Context context, int size, int color, boolean solid, ArrowDirection direct){
		float fSize = Float.parseFloat(size + "");
		PointF p1= new PointF(0, 0);
		PointF p2= new PointF(fSize/2, fSize/2);
		PointF p3= new PointF(0, fSize);
		
		Path arrowPath = new Path();
		arrowPath.reset();
		arrowPath.moveTo(p1.x, p1.y);
		arrowPath.lineTo(p2.x, p2.y);
		arrowPath.lineTo(p3.x, p3.y);
		
		Bitmap arrow = Bitmap.createBitmap(size, size, Config.ARGB_8888);
		Canvas c = new Canvas(arrow);
		Paint p = new Paint();
		p.setAntiAlias(true);
		if(!solid){
			int lineWidth = AwDisplayUtil.dip2px(context, 2);
			p.setStyle(Style.STROKE);
			p.setStrokeWidth(lineWidth);
		}else{
			p.setStyle(Style.FILL);
		}
		p.setColor(color);
		c.drawPath(arrowPath, p);
		
		Bitmap result = direct.getDegree() == 0 
				? arrow : getRotatedBitmap(arrow, direct.getDegree());
		return result;
		
	}
	
	/**
	 * 绘制十字图标
	 * @param context
	 * @param sideLen 图标边长
	 * @param lineWidth (单位：dp)
	 * @param color 十字线的颜色
	 * @return
	 */
	public static Bitmap drawCrossIcon(Context context, int sideLen, int lineWidth, int color){
		Point lp = new Point(0, sideLen/2);
		Point rp = new Point(sideLen, sideLen/2);
		Point tp = new Point(sideLen/2, 0);
		Point bp = new Point(sideLen/2, sideLen);
		
		Path path = new Path();
		path.moveTo(lp.x, lp.y);
		path.lineTo(rp.x, rp.y);
		path.moveTo(tp.x, tp.y);
		path.lineTo(bp.x, bp.y);
		
		Bitmap cross = Bitmap.createBitmap(sideLen, sideLen, Config.ARGB_8888);
		Canvas c = new Canvas(cross);
		int lineWidthInDp = AwDisplayUtil.dip2px(context, lineWidth == -1 ? 2 : lineWidth);
		Paint paint = createLinePaint(lineWidthInDp, color);
		c.drawPath(path, paint);
		return cross;
	}
	
	/**
	 * 绘制十字图标
	 * @param context
	 * @param sideLen 图标边长
	 * @param lineWidth (单位：dp)
	 * @param color 十字线的颜色
	 * @return
	 */
	public static Bitmap drawDeclineIcon(Context context, int sideLen, int lineWidth, int color){
		Point lp = new Point(0, sideLen/2);
		Point rp = new Point(sideLen, sideLen/2);
		
		Path path = new Path();
		path.moveTo(lp.x, lp.y);
		path.lineTo(rp.x, rp.y);
		
		Bitmap cross = Bitmap.createBitmap(sideLen, sideLen, Config.ARGB_8888);
		Canvas c = new Canvas(cross);
		int lineWidthInDp = AwDisplayUtil.dip2px(context, lineWidth == -1 ? 2 : lineWidth);
		Paint paint = createLinePaint(lineWidthInDp, color);
		c.drawPath(path, paint);
		return cross;
	}
	
	private static Paint createLinePaint(int lineWidth, int color){
		Paint p = new Paint();
		p.setAntiAlias(true);
		p.setStyle(Style.STROKE);
		p.setStrokeWidth(lineWidth);
		p.setColor(color);
		p.setStrokeCap(Cap.ROUND);
		p.setStrokeJoin(Join.BEVEL);
		return p;
	}

    /**
     * 将bitmap中的某种颜色值替换成新的颜色
     * @param oldBitmap
     * @param oldColor
     * @param newColor
     * @return
     */
    public static Bitmap replaceBitmapColor(Bitmap oldBitmap,int oldColor,int newColor) {
        Bitmap mBitmap = oldBitmap.copy(Config.ARGB_8888, true);
        //循环获得bitmap所有像素点
        int mBitmapWidth = mBitmap.getWidth();
        int mBitmapHeight = mBitmap.getHeight();
        int mArrayColorLengh = mBitmapWidth * mBitmapHeight;
        for (int i = 0; i < mBitmapHeight; i++) {
            for (int j = 0; j < mBitmapWidth; j++) {
                //获得Bitmap 图片中每一个点的color颜色值
                //将需要填充的颜色值如果不是
                //在这说明一下 如果color 是全透明 或者全黑 返回值为 0
                //getPixel()不带透明通道 getPixel32()才带透明部分 所以全透明是0x00000000
                //而不透明黑色是0xFF000000 如果不计算透明部分就都是0了
                int color = mBitmap.getPixel(j, i);
                //将颜色值存在一个数组中 方便后面修改
                if (color == oldColor) {
                    mBitmap.setPixel(j, i, newColor);  //将白色替换成透明色
                }
            }
        }
        return mBitmap;
    }

	public enum ArrowDirection{
		LEFT(180),
		RIGHT(0),
		TOP(270),
		BOTTOM(90);
		
		int degree;
		ArrowDirection(int degree){
			this.degree = degree;
		}
		
		public int getDegree(){
			return degree;
		}
	}


	public static byte[] bitmap2Bytes(Bitmap bitmap){
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bitmap.compress(CompressFormat.JPEG, 100, baos);
		byte[] datas = baos.toByteArray();
		return  datas;
	}

	public static Bitmap Bytes2bitmap (byte[] bytes){
		Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
		return bitmap;
	}

	/**
	 * 保存base64图片到相册
	 * @param base64Str
	 * @param path
	 * @param insertAlbum             是否直接插入android系统图库
	 */
	public static String base64ToImgFile(Context mContext , String base64Str,String path,boolean insertAlbum){
		try {
			Bitmap bt = base64ToBitmp(base64Str);
			if(bt!= null){
				if(insertAlbum) {
					//把文件插入到系统图库
					path = MediaStore.Images.Media.insertImage(mContext.getContentResolver(), bt, UUID.randomUUID().toString() + ".png", "description");

				}else{
					saveBitmapToFile(bt,path);
					//保存图片后发送广播通知更新数据库
					File file = new File(path);
					Uri uri = Uri.fromFile(file);
					mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return path;
	}

	/**
	 * 矢量图转Bitmap
	 *
	 * @param drawableId 矢量图ID
	 * @return
	 */
	public static Bitmap getBitmapFromVectorDrawable(int drawableId) {
		Drawable drawable = AwBaseApplication.getInstance().getDrawable(drawableId);
		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
			drawable = (DrawableCompat.wrap(drawable)).mutate();
		}

		Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
				Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
		drawable.draw(canvas);

		return bitmap;
	}

	/**
	 * 矢量图转Bitmap
	 *
	 * @param context
	 * @param drawable 矢量图Drawable
	 * @return
	 */
	public static Bitmap getBitmapFromVectorDrawable(Context context, Drawable drawable) {
		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
			drawable = (DrawableCompat.wrap(drawable)).mutate();
		}

		Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
				Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
		drawable.draw(canvas);

		return bitmap;
	}
}
